use crate::vtt::{VttLine, VttRegion, VttStyle};
use chrono::{DateTime, Utc};
use napi_derive_ohos::napi;
use rsubs_lib::VTT;
use std::{fs::File, io::Read};

#[napi]
pub struct ParseVtt {
    path: String,
    instance: Option<VTT>,
}

#[napi]
impl ParseVtt {
    #[napi(constructor)]
    pub fn new(path: String) -> Self {
        ParseVtt {
            path,
            instance: None,
        }
    }

    #[napi]
    pub async unsafe fn init(&mut self) {
        if let Ok(mut file) = File::open(&self.path) {
            let mut contents = String::new();
            if let Ok(_) = file.read_to_string(&mut contents) {
                if let Ok(result) = VTT::parse(contents) {
                    self.instance = Some(result);
                }
            }
        }
    }

    #[napi]
    pub async unsafe fn read_lines(&mut self) -> Vec<VttLine> {
        let mut list: Vec<VttLine> = vec![];
        if let Some(result) = &self.instance {
            for line in &result.lines {
                let start_opt =
                    DateTime::<Utc>::from_timestamp_millis(line.start.millisecond().into());
                let end_opt = DateTime::<Utc>::from_timestamp_millis(line.end.millisecond().into());
                match (start_opt, end_opt) {
                    (Some(start), Some(end)) => {
                        list.push(VttLine {
                            text: line.text.to_string(),
                            settings: line.settings.clone(),
                            identifier: line.identifier.clone(),
                            end_timestamp_millis: end.timestamp_millis(),
                            start_timestamp_millis: start.timestamp_millis(),
                        });
                    }
                    _ => {}
                }
            }
        }
        list
    }

    #[napi]
    pub async unsafe fn read_regions(&mut self) -> Vec<VttRegion> {
        let mut list: Vec<VttRegion> = vec![];
        if let Some(result) = &self.instance {
            for region in &result.regions {
                let mut region_anchor_x = None;
                let mut region_anchor_y = None;
                if let Some(ra) = region.region_anchor {
                    region_anchor_x = Some(ra.0 as f64);
                    region_anchor_y = Some(ra.1 as f64);
                }
                let mut viewport_anchor_x = None;
                let mut viewport_anchor_y = None;
                if let Some(ra) = region.viewport_anchor {
                    viewport_anchor_x = Some(ra.0 as f64);
                    viewport_anchor_y = Some(ra.1 as f64);
                }
                list.push(VttRegion {
                    id: region.id.clone(),
                    width: region.width.map(|f| f as f64),
                    lines: region.lines,
                    region_anchor_x,
                    region_anchor_y,
                    viewport_anchor_x,
                    viewport_anchor_y,
                    scroll: region.scroll,
                });
            }
        }
        list
    }

    #[napi]
    pub async unsafe fn read_styles(&mut self) -> Vec<VttStyle> {
        let mut list: Vec<VttStyle> = vec![];
        if let Some(result) = &self.instance {
            for style in &result.styles {
                list.push(VttStyle {
                    selector: style.selector.clone(),
                    entries: style.entries.clone(),
                });
            }
        }
        list
    }
}
